package fasilkom.antz;

import java.awt.Font;
import java.awt.Graphics2D;

import com.golden.gamedev.GameObject;
import com.golden.gamedev.gui.TLabel;
import com.golden.gamedev.gui.toolkit.FrameWork;
import com.golden.gamedev.gui.toolkit.TComponent;
import com.golden.gamedev.gui.toolkit.TContainer;
import com.golden.gamedev.object.GameFont;
import com.golden.gamedev.object.Sprite;
import com.golden.gamedev.object.SpriteGroup;
import com.golden.gamedev.object.background.ImageBackground;

import fasilkom.antz.gui.Button;
import fasilkom.antz.gui.CustomTheme;
import fasilkom.antz.gui.FloatPanel;
import fasilkom.antz.gui.RecruitButton;
import fasilkom.antz.gui.UnrecruitButton;
import fasilkom.antz.sprite.FontSprite;


public class WorldMap extends GameObject {

	ImageBackground background;
	Sprite pointer;
	Sprite sarang;
	Sprite level1;

	Sprite panelEnter;
	Sprite yes;
	Sprite no;

	Sprite panelSarang;
	FontSprite recruitText;
	FontSprite shopText;

	Sprite panelRecruit;
	FontSprite warrior;
	FontSprite rogue;
	FontSprite tank;

	Sprite test;

	SpriteGroup windowSure;
	SpriteGroup recruit;
	SpriteGroup anthill;

	boolean start;
	Antz main;
	
	private FrameWork gui;
	private TContainer panelMain;
	private TContainer panelSure;
	private TContainer activePanel;
	private TContainer panelRecruitment;
	private TContainer panelArmy;
	private TComponent[][] panelArmyTable;

	public WorldMap(Antz parent) {
		super(parent);
		main = parent;
	}

	public void initResources() {
		pointer = new Sprite(getImage("assets/pointer.png"));
		level1 = new Sprite(getImage("assets/level1.png"));
		sarang = new Sprite(getImage("assets/anthill2.png"));

		test = new Sprite(getImage("assets/goal.png"));

		GameFont font = fontManager.getFont(new Font("Kristen ITC", Font.BOLD, 14));

		windowSure = new SpriteGroup("sure");
		panelEnter = new Sprite(getImage("assets/enterwindow.png"));
		yes = new Sprite(getImage("assets/yes.png"));
		no = new Sprite(getImage("assets/no.png"));
		windowSure.add(panelEnter);
		windowSure.add(yes);
		windowSure.add(no);
		windowSure.setActive(false);

		anthill = new SpriteGroup("anthill");
		panelSarang = new Sprite(getImage("assets/anthill.png"));
		//recruitText = new FontSprite("Recruitment", font);
		//shopText = new FontSprite("Item Shop", font);
		anthill.add(panelSarang);
		//anthill.add(recruitText);
		//anthill.add(shopText);
		anthill.setActive(false);

		recruit = new SpriteGroup("recruit");
		panelRecruit = new Sprite(getImage("assets/anthill.png"));
		//warrior = new FontSprite("Warrior", font);
		//tank = new FontSprite("Tank", font);
		//rogue = new FontSprite("Rogue", font);


		panelSarang.setLocation(400-panelSarang.getWidth()/2, 50);
		//recruitText.setLocation(panelSarang.getX() + 30, panelSarang.getY() + 40);
		//shopText.setLocation(panelSarang.getX() + 30, panelSarang.getY() + 60);

		sarang.setLocation(390, 353);
		level1.setLocation(186, 389);

		panelEnter.setLocation(400-panelEnter.getWidth()/2, 50);
		yes.setLocation(panelEnter.getX() + 30, panelEnter.getY()+panelEnter.getHeight()-80);
		no.setLocation(panelEnter.getX() + yes.getWidth() + 100, panelEnter.getY()+panelEnter.getHeight()-80);


		background = new ImageBackground(getImage("assets/world-map.jpg"));
		
		// Init GUI
		initGui();
	}

	public void render(Graphics2D g) {
		background.render(g);

		//test.render(g);

		if(windowSure.isActive()){
			windowSure.render(g);
		}

		if(anthill.isActive()){
			anthill.render(g);
		}

		sarang.render(g);
		level1.render(g);

		// GUI
		gui.render(g);
		
		// Mouse pointer
		pointer.render(g);
	}

	public void update(long elapsedTime){
		background.update(elapsedTime);
		pointer.update(elapsedTime);
		sarang.update(elapsedTime);
		level1.update(elapsedTime);

		windowSure.update(elapsedTime);
		anthill.update(elapsedTime);
		

		test.update(elapsedTime);
		updatePointer(elapsedTime);
		
		if(isMouseOver(sarang)){
			sarang.setImage(getImage("assets/anthill2-sel.png"));
			level1.setImage(getImage("assets/level1.png"));
		}
		else if(isMouseOver(level1)){
			sarang.setImage(getImage("assets/anthill2.png"));
			level1.setImage(getImage("assets/level1-sel.png"));
		}
		else {
			sarang.setImage(getImage("assets/anthill2.png"));
			level1.setImage(getImage("assets/level1.png"));
		}

		if(click()){
			if(isMouseOver(sarang)){
//				anthill.setActive(true); // REMOVE
				if (activePanel == null)
					setActivePanel(panelMain);
			}
			else if(isMouseOver(level1)){
//				windowSure.setActive(true); // REMOVE
				if (activePanel == null)
					setActivePanel(panelSure);
			}
			else if(isMouseOver(no) && windowSure.isActive()){ // REMOVE
				windowSure.setActive(false);
			}
			else if(isMouseOver(yes) && windowSure.isActive()){ // REMOVE
				parent.nextGameID = Antz.STAGE_1;
				finish();
			}
			/*else if(isMouseOver(recruitText) && anthill.isActive()){ // REMOVE
				System.out.println("rekruit");
			}
			else if(isMouseOver(shopText) && anthill.isActive()){ // REMOVE
				System.out.println("shopping");
			}*/
			else { // REMOVE
				anthill.setActive(false);
				windowSure.setActive(false);
			}
		}
		
		// GUI
		gui.update();
	}

	private void updatePointer(long elapsedTime) {
		// Mouse pointer
		if (bsInput.isMouseExists()) {
			pointer.setLocation(getMouseX(), getMouseY());
		}else {
			pointer.setLocation(-pointer.getWidth(), -pointer.getHeight());
		}
	}

	public boolean isMouseOver(Sprite s) {
		double mx = getMouseX() + background.getX() +
			background.getClip().x;
		double my = getMouseY() + background.getY() +
			background.getClip().y;
		return mx >= s.getX() && mx <= s.getX() + s.getWidth() &&
				my >= s.getY() && my <= s.getY() + s.getHeight() &&
				background.getClip().contains(getMouseX(), getMouseY());
	}
	
	/**
	 * Initialize the GUI.
	 */
	private void initGui() {
		gui = new FrameWork(bsInput, getWidth(), getHeight());
		gui.installTheme(new CustomTheme(this));
		
		// Main Panel
		initGuiPanelMain(200, 30, 20);
		
		// Recruitment Panel
		initGuiPanelRecruitment(120, 30, 10);
		
		// Army Panel
		initGuiPanelArmy(120, 30, 10);
		
		// Panel Sure
		initGuiPanelSure(400, 120, 30, 20);
	}
	
	/**
	 * Initialize the GUI, that is the main panel when the nest clicked.
	 */
	private void initGuiPanelMain(int WIDTH, int HEIGHT, int SPACING) {
		int Y = -HEIGHT;
		
		// Panel
		panelMain = new FloatPanel(this, "Anthill", 0, 0, WIDTH + 2 * SPACING, 3 * HEIGHT + 4 * SPACING + CustomTheme.TITLE_HEIGHT);
		panelMain.setLocation((gui.getWidth() - panelMain.getWidth()) / 2, (gui.getHeight() - panelMain.getHeight()) / 2);
		panelMain.setVisible(false);
		gui.add(panelMain);
		
		// Button "Recruitment"
		panelMain.add(new Button("Recruitment", SPACING, Y += HEIGHT + SPACING, WIDTH, HEIGHT) {
			public void doAction() {
				super.doAction();
				setActivePanel(panelRecruitment);
			}});
		
		// Button "Army"
		panelMain.add(new Button("Army", SPACING, Y += HEIGHT + SPACING, WIDTH, HEIGHT) {
			public void doAction() {
				super.doAction();
				setActivePanel(panelArmy);
			}});
		
		// Button "Item Shop"
		panelMain.add(new Button("Item Shop", SPACING, Y += HEIGHT + SPACING, WIDTH, HEIGHT) {
			public void doAction() {
				super.doAction();
				setActivePanel(null); // TODO item shop
			}});
	}
	
	/**
	 * Initialize the GUI, that's the recruitment panel.
	 */
	private void initGuiPanelRecruitment(int WIDTH, int HEIGHT, int SPACING) {
		int Y = -HEIGHT;
		
		// Available army types list
		String[] availableTypes = Status.TYPES;
		int[] antsNeeded = RecruitButton.antsNeeded;

		// Panel
		panelRecruitment = new FloatPanel(this, "Recruitment", 0, 0, 4 * WIDTH + 5 * SPACING, 9 * HEIGHT + 10 * SPACING + CustomTheme.TITLE_HEIGHT);
		panelRecruitment.setLocation((gui.getWidth() - panelRecruitment.getWidth()) / 2, (gui.getHeight() - panelRecruitment.getHeight()) / 2);
		panelRecruitment.setVisible(false);
		gui.add(panelRecruitment);
		
		// Table header
		panelRecruitment.add(new TLabel("Type", SPACING, Y += HEIGHT + SPACING, WIDTH, HEIGHT));
		panelRecruitment.add(new TLabel("Level", 2 * SPACING + WIDTH, Y, WIDTH, HEIGHT));
		panelRecruitment.add(new TLabel("Ants Needed", 3 * SPACING + 2 * WIDTH, Y, WIDTH, HEIGHT));
		
		// List of available army
		for (int i = 0; i < antsNeeded.length; ++i) {
			for (int type = 0; type < availableTypes.length - 1; ++type) {
				
				// type
				panelRecruitment.add(new TLabel(availableTypes[type], SPACING, Y += HEIGHT + SPACING, WIDTH, HEIGHT));
				// level
				panelRecruitment.add(new TLabel(String.valueOf(i + 1), 2 * SPACING + WIDTH, Y, WIDTH, HEIGHT));
				// ants needed
				panelRecruitment.add(new TLabel(String.valueOf(antsNeeded[i]), 3 * SPACING + 2 * WIDTH, Y, WIDTH, HEIGHT));
				// button "Recruit"
				panelRecruitment.add(new RecruitButton(parent, type, i, 4 * SPACING + 3 * WIDTH, Y, WIDTH, HEIGHT));
				
			}
		}
		
		// Num of available ants
		panelRecruitment.add(new AntsAvailLabel(SPACING, Y += 2 * (HEIGHT + SPACING), WIDTH * 4 + SPACING * 3, HEIGHT));
	}
	
	/**
	 * Initialize the GUI, that's the army panel.
	 */
	private void initGuiPanelArmy(int WIDTH, int HEIGHT, int SPACING) {
		int Y = -HEIGHT;

		// Panel
		panelArmy = new FloatPanel(this, "Army", 0, 0, 5 * WIDTH + 6 * SPACING, 11 * HEIGHT + 12 * SPACING + CustomTheme.TITLE_HEIGHT);
		panelArmy.setLocation((gui.getWidth() - panelArmy.getWidth()) / 2, (gui.getHeight() - panelArmy.getHeight()) / 2);
		panelArmy.setVisible(false);
		gui.add(panelArmy);
		
		// Table header
		panelArmy.add(new TLabel("No", SPACING, Y += HEIGHT + SPACING, WIDTH, HEIGHT));
		panelArmy.add(new TLabel("Type", 2 * SPACING + WIDTH, Y, WIDTH, HEIGHT));
		panelArmy.add(new TLabel("Level", 3 * SPACING + 2 * WIDTH, Y, WIDTH, HEIGHT));
		panelArmy.add(new TLabel("Ants", 4 * SPACING + 3 * WIDTH, Y, WIDTH, HEIGHT));
		
		// List of available army
		panelArmyTable = new TComponent[8][5];
		for (int i = 0; i < RecruitButton.PLAYERS_MAX; ++i) {
			
			// no
			panelArmy.add(panelArmyTable[i][0] = new TLabel("", SPACING, Y += HEIGHT + SPACING, WIDTH, HEIGHT));
			// type
			panelArmy.add(panelArmyTable[i][1] = new TLabel("", 2 * SPACING + WIDTH, Y, WIDTH, HEIGHT));
			// level
			panelArmy.add(panelArmyTable[i][2] = new TLabel("", 3 * SPACING + 2 * WIDTH, Y, WIDTH, HEIGHT));
			// ants (needed)
			panelArmy.add(panelArmyTable[i][3] = new TLabel("", 4 * SPACING + 3 * WIDTH, Y, WIDTH, HEIGHT));
			// button "Release"
			panelArmy.add(panelArmyTable[i][4] = new UnrecruitButton(this, i, 5 * SPACING + 4 * WIDTH, Y, WIDTH, HEIGHT));
			
			panelArmyTable[i][4].setVisible(false);
		}
		
		// Num of available ants
		panelArmy.add(new AntsAvailLabel(SPACING, 10 * HEIGHT + 11 * SPACING, WIDTH * 4 + SPACING * 3, HEIGHT));
	}
	
	/**
	 * Initialize the GUI, currently for launch level 1 only.
	 */
	private void initGuiPanelSure(int TOTAL_WIDTH, int WIDTH, int HEIGHT, int SPACING) {
		// Panel
		panelSure = new FloatPanel(this, "Enter Map", 0, 0, TOTAL_WIDTH, 3 * SPACING + 2 * HEIGHT + CustomTheme.TITLE_HEIGHT);
		panelSure.setLocation((gui.getWidth() - panelSure.getWidth()) / 2, (gui.getHeight() - panelSure.getHeight()) / 2);
		panelSure.setVisible(false);
		gui.add(panelSure);
		
		// Message
		panelSure.add(new TLabel("Do you want to enter this map?",  SPACING, SPACING, TOTAL_WIDTH - 2 * SPACING, HEIGHT));
		
		// Button "No"
		panelSure.add(new Button("No", TOTAL_WIDTH - 2 * (SPACING + WIDTH), HEIGHT + 2 * SPACING, WIDTH, HEIGHT) {
			public void doAction() {
				super.doAction();
				setActivePanel(null); 
			}});
		
		// Button "Yes"
		panelSure.add(new Button("Yes", TOTAL_WIDTH - SPACING - WIDTH, HEIGHT + 2 * SPACING, WIDTH, HEIGHT) {
			public void doAction() {
				super.doAction();
				setActivePanel(null);
				parent.nextGameID = Antz.STAGE_1;
				finish();
			}});
	}
	
	public void setActivePanel(TContainer panel) {
		// Tampilkan army sesuai keadaan sekarang
		
		if (panel == panelArmy) {
			panelArmyRefresh();
		}
		
		// Yang sebenarnya
		
		if (activePanel != null && activePanel.isVisible())
			activePanel.setVisible(false);
		if (panel != null && !panel.isVisible())
			panel.setVisible(true);
		activePanel = panel;
		
	}

	public void panelArmyRefresh() {
		if (panelArmyTable == null)
			return;
		
		// Tampilkan untuk yang ada
		int i = 0;
		for (Sprite s : ((Antz) parent).PLAYER_GROUP.getSprites()) {
			if (s != null && s.isActive()) {
				GameChar ant = (GameChar) s;
				
				((TLabel) panelArmyTable[i][0]).setText((i + 1) + ".");
				((TLabel) panelArmyTable[i][1]).setText(ant.status.getTypeString());
				((TLabel) panelArmyTable[i][2]).setText(String.valueOf(ant.status.level + 1));
				((TLabel) panelArmyTable[i][3]).setText(String.valueOf(RecruitButton.antsNeeded[ant.status.level]));
				panelArmyTable[i][0].setVisible(true);
				panelArmyTable[i][1].setVisible(true);
				panelArmyTable[i][2].setVisible(true);
				panelArmyTable[i][3].setVisible(true);
				if (((GameChar) s).status.type != Status.Z)
					panelArmyTable[i][4].setVisible(true);
				++i;
			}
		}
		
		// Sembunyikan yang tidak ada (jika jumlah tidak sampai 8)
		for (; i < RecruitButton.PLAYERS_MAX; ++i) {
			for (int j = 0; j < 5; ++j)
				panelArmyTable[i][j].setVisible(false);
		}
	}

	// NESTED CLASS //
	
	private final class AntsAvailLabel extends TLabel {
		int antSaved = -1;

		private AntsAvailLabel(int x, int y, int w, int h) {
			super("", x, y, w, h);
		}

		public void update() {
			super.update();
			if (antSaved != ((Antz) parent).antSaved) {
				antSaved = ((Antz) parent).antSaved;
				setText("Ants available: " + antSaved);
			}
		}
	}
}
